﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "DynamicPanel.h"
#include "UiConfiguration.h"

// gcmp
#include "IUiManager.h"
#include "ICommandManager.h"

// QT
#include <QLayout>
#include <QFormLayout.h>
#include <QPushButton>
#include <QVariant>
#include <QEvent>
#include <QMouseEvent>

using namespace gcmp;

namespace
{
    void clearLayout(QLayout* layout)
    {
        if (layout) {
            while (layout->count() > 0) {
                QLayoutItem* item = layout->takeAt(0);
                if (item) {
                    item->widget()->deleteLater();
                    delete item;
                }
            }
        }
    }

    gcmp::IWidget* GetDock(const std::wstring& name)
    {
        IUiManager* pUiManager = IUiManager::Get();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiManager, L"断言`pUiManager`失败",L"GDMPLab",L"2024-03-30");
        IDockManager* pDockManager = pUiManager->GetDockManager();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDockManager, L"断言`pDockManager`失败",L"GDMPLab",L"2024-03-30");

        IDock* pDock = pDockManager->GetDock(name);
        if (pDock == nullptr)
        {
            return nullptr;
        }
        return pDock->GetWidget();
    }
}

namespace Sample
{
    DynamicPanel::DynamicPanel(QWidget* parent /*= Q_NULLPTR*/, Qt::WindowFlags f /*= Qt::WindowFlags() */)
        : QWidget(parent, f)
    {
        m_pLayout = new QHBoxLayout();
        setLayout(m_pLayout);
    }

    DynamicPanel* DynamicPanel::Get(const std::wstring& name, bool bAutoCreate /*= true*/)
    {
        IUiManager* pUiManager = IUiManager::Get();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiManager, L"断言`pUiManager`失败",L"GDMPLab",L"2024-03-30");
        IDockManager* pDockManager = pUiManager->GetDockManager();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDockManager, L"断言`pDockManager`失败",L"GDMPLab",L"2024-03-30");

        DynamicPanel* pPanel = dynamic_cast<DynamicPanel*>(GetDock(name));

        if (!bAutoCreate) {
            return pPanel;
        }

        if (!pPanel) {

            OwnerPtr<IDock> opDock = pDockManager->CreateDock(name, L"预设参数");
            OwnerPtr<DynamicPanel> opPanel = NEW_AS_OWNER_PTR(DynamicPanel);
            DBG_WARN_AND_RETURN_NULLPTR_UNLESS(opPanel, L"断言`opPanel`失败",L"GDMPLab",L"2024-03-30");
            opPanel->m_pDock = opDock.get();
            pPanel = opPanel.get();
            opDock->SetWidget(std::move(opPanel));
            opDock->SetFloating(true);
            pDockManager->AddDock(std::move(opDock), gcmp::DockArea::Right, gcmp::DockOrientation::Vertical);
        }
        return pPanel;
    }

    void DynamicPanel::Show()
    {
        if (m_pDock) {
            m_pDock->Show();
            m_pDock->Raise();
        }
        else
        {
            this->show();
        }
    }

    void DynamicPanel::Hide()
    {
        if (m_pDock) {
            m_pDock->Hide();
        }
        else
        {
            this->hide();
        }
    }

    void DynamicPanel::SetCaption(const std::wstring& caption)
    {
        if (m_pDock) {
            m_pDock->SetTitle(caption);
        }
        else {
            this->setWindowTitle(QString::fromStdWString(caption));
        }
    }

    void DynamicPanel::Update(const std::wstring& caption, const std::vector<std::wstring>& commandIds)
    {
        SetCaption(caption);
        clearLayout(m_pLayout);
        if (!commandIds.empty())
        {
            FOR_EACH(commandId, commandIds)
            {
                const CommandButton& commandButton = FindButtonDefinition(commandId);

                QIcon qIcon(QString::fromStdWString(commandButton.iconDirectory));
                QPushButton* pBtn = NEW_AS_QT(QPushButton/*, QString::fromStdWString(commandButton.caption)*/);
                DBG_WARN_AND_CONTINUE_UNLESS(pBtn, L"断言`pBtn`失败",L"GDMPLab",L"2024-03-30");
                pBtn->setIcon(qIcon);
                pBtn->setToolTip(QString::fromStdWString(commandButton.caption));
                pBtn->setProperty("CommandId", QVariant(QString::fromStdWString(commandId)));
                pBtn->installEventFilter(this);
                m_pLayout->addWidget(pBtn);
            }
            Show();
        }
        else
        {
            Hide();
        }
    }

    void DynamicPanel::SetEnabled(bool bEnable)
    {
        //setEnabled(bEnable);
    }

    bool DynamicPanel::eventFilter(QObject* watched, QEvent* event)
    {
        if (watched && event)
        {
            if (QMouseEvent* pMouseEvent = dynamic_cast<QMouseEvent*>(event))
            {
                if (pMouseEvent->button() == Qt::LeftButton)
                {
                    if (QPushButton* pPushBtn = qobject_cast<QPushButton*>(watched))
                    {
                        std::wstring cmdId = pPushBtn->property("CommandId").toString().toStdWString();
                        OnClicked(cmdId);
                        return true;
                    }
                }
            }
        }
        return QWidget::eventFilter(watched, event);
    }

    void DynamicPanel::OnClicked(const std::wstring& commandId)
    {
        ICommandManager* pCommandManager = ICommandManager::Get();
        if (pCommandManager)
        {
            pCommandManager->SendCommand(commandId);
        }
    }
}
